package org.flowable.pz.service;

import org.flowable.pz.entity.dto.FlowableProcessDto;
import org.flowable.pz.entity.dto.FlowablePageDto;
import org.flowable.pz.entity.dto.FlowableTaskDto;
import org.flowable.pz.entity.vo.FlowableProcessQueryVo;
import org.flowable.pz.entity.vo.FlowableTaskQueryVo;

import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * 流程实例相关
 * */
public interface FlowableProcess {

    /**
     * 发起流程，生成一个实例
     * @param processDefinitionKey 流程定义 key
     * @param variable 流程变量 会放入流程中，流程中需要使用的参数，都从这里放入
     * */
    String startProcess(@NotNull(message = "流程定义参数 processDefinitionKey 不能为空！") String processDefinitionKey, Map<String, Object> variable);

    /**
     * 取消流程（删除）
     * 取消，相当于把流程删除了，实际实现使用 flowable 提供的 delete 功能
     * @param processInstanceId 流程定义 key
     * @param cancelComment 取消原因
     * */
    void cancelProcess(@NotNull(message = "流程实例 id 参数 processInstanceId 不能为空！") String processInstanceId, String cancelComment);

    /**
     * 终止流程
     * 跟取消实现上的区别：取消是相当于来了个逻辑删除，终止则是从当前任务挪到追后一个结束节点
     * @param processInstanceId 流程定义 key
     * @param stopComment 取消原因
     * */
    void stopProcess(@NotNull(message = "流程实例 id 参数 processInstanceId 不能为空！") String processInstanceId, String stopComment);

    /**
     * 挂起流程
     * 如果是挂起状态，就激活
     * 如果是激活状态，就挂起
     * */
    void suspendProcess(@NotNull(message = "流程实例 id 参数 processInstanceId 不能为空！") String processInstanceId);

    /**
     * 流程实例列表，查询所有实例（管理员用）
     * */
    FlowablePageDto<FlowableProcessDto> processList(FlowableProcessQueryVo queryVo);

    /**
     * 流程实例列表（我发起的）
     * */
    FlowablePageDto<FlowableProcessDto> myProcessList(FlowableProcessQueryVo queryVo);

    /**
     * 审批流程
     * @param taskId 任务id
     * @param comment 备注
     * */
    void completeProcess(@NotNull(message = "任务 id 参数 taskId 不能为空！！！") String taskId, String comment, Map<String, Object> variables);

    /**
     * 任务列表，代办任务
     * */
    FlowablePageDto<FlowableTaskDto> todoTaskList(FlowableTaskQueryVo queryVo);

    /**
     * 任务列表，已办任务
     * */
    FlowablePageDto<FlowableTaskDto> approvedTaskList(FlowableTaskQueryVo queryVo);

    /**
     * 流程变量
     * */
    Map<String, Object> variables(@NotNull(message = "流程实例 id 参数 processId 不能为 null")String processId);

    /**
     * 流转记录,只取用户节点的
     * */
    List<FlowableTaskDto> records(@NotNull(message = "流程实例 id 参数 processId 不能为 null")String processId);

    /**
     * 流程图
     * */
    byte[] processDiagram(@NotNull String processInstanceId) throws IOException;
}
